from abstractNodeKomunikacija import AbstractNodeKomunikacija
import time
from time import sleep
from commands import Commands
from udpServerNode import udpServerNode
from udpClientNode import UDPCLientNode

class UDPNode(AbstractNodeKomunikacija):
    def __init__(self, opseg, listenPort, poslednjih10Klijenata):
        AbstractNodeKomunikacija.__init__(self, listenPort)  # ALI PAM TIM JOS (TUBC TUBC)
        self.requestID = 1
        self.poslednjih10Klijenata = poslednjih10Klijenata
        self.zahtevi = {}  # mapa
        self.rola = ""
        self.chunkStates = []  # kolekcija
        self.opseg = opseg
        self.sviServeri = []
        
    def obradiPaket(self, recieveAddress, recievePort, requestID, komanda, telo):
        print "KLIJENT OBRADI PAKET"
        print requestID
        print self.zahtevi
        if(komanda == self.zahtevi[int(requestID)]):
            # telo je rola i lista svih servera
            self.sviServeri = []
            celaPoruka = telo.split(';')
            self.rola = celaPoruka[0]
            print "Rola je" + self.rola + "\n Citam sve server..."
            brServera = str(celaPoruka[1])
            j = 2
            for i in range(0, int(brServera)):
                self.sviServeri.append((celaPoruka[j], celaPoruka[j + 1]))
                j = j + 2
            
            print self.sviServeri
            print "Citam Chunck stateove"
            
            brojChunkova = celaPoruka[j]
            
            print "BROJ CHUNKOVA: ", brojChunkova
            
            self.chunkStates = []
            j = j + 1
            for i in range(0, int(brojChunkova)):
                self.chunkStates.append([celaPoruka[j], celaPoruka[j+1]])
                j+=2
            print self.chunkStates
            self.zahtevi.pop(int(requestID))
            
    def start(self):
        print "UDP NODE START"
        self.startRecieving()
        print "PROSO"
        self.obratiSePoslednjih10Klijenata()
         
    
    def obratiSePoslednjih10Klijenata(self):
        print "Oracanje poslednjih 10 klijenata"
        
        print "Poslednjih 10 SIze :" + str(self.poslednjih10Klijenata.__len__())
        sizeOfPoslednjih10Klijenata = self.poslednjih10Klijenata.__len__()
        if sizeOfPoslednjih10Klijenata == 0:
            # pravi se novi udpServerNode
            udpsn = udpServerNode(None, self.requestID+1, self.opseg, self.listenPort, self.sviServeri)
            self.stopRecieving()
            udpsn.start()
            return 
        komanda = Commands.NEW_NODE
        teloPoruke = "EMPTY"
        while True:
            for currentClient  in self.poslednjih10Klijenata:
                self.sendPaket(currentClient[0], currentClient[1], self.requestID, komanda, teloPoruke)
                self.zahtevi.update({self.requestID : Commands.NEW_NODE_RESPONSE})
                #print self.zahtevi ,"Mater ti jebem onu nenromalnu a ovde nsii prazna"
                if self.waitForResponse(self.requestID):
                    if self.rola  == Commands.ROLE_SERVER:
                        udpsn = udpServerNode(self.chunkStates, self.requestID+1, self.opseg, self.listenPort, self.sviServeri)
                        self.stopRecieving()
                        udpsn.start()
                        return 
                    else:
                        if self.rola == Commands.ROLE_CLIENT:
                            client = UDPCLientNode(self.requestID+1, self.opseg, self.sviServeri, self.listenPort)
                            self.stopRecieving()
                            client.start()
                            return
                    self.requestID +=1
                    return
                else:
                    print "WARN: FAILED ONECE"
                #print self.zahtevi ,"Mater ti jebem onu nenromalnu"
                self.zahtevi.pop(self.requestID)
                self.requestID+=1    
                
    def waitForResponse(self, requestID):
        getCurTime = lambda : float(round(time.time() * 1000))
        startTime = getCurTime()
        trenutnoVreme = startTime
        while (trenutnoVreme - startTime) < 15000 and self.zahtevi.has_key(requestID):
            sleep(1)
            trenutnoVreme = getCurTime()
        return not self.zahtevi.has_key(requestID) 
        
    
   
        
